package com.freshman_registration.service.impl;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.freshman_registration.mapper.PaymentItemMapper;
import com.freshman_registration.mapper.PaymentRecordMapper;
import com.freshman_registration.pojo.PaymentItem;
import com.freshman_registration.pojo.PaymentRecord;
import com.freshman_registration.service.PaymentService;
import com.freshman_registration.util.Result;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentItemMapper paymentItemMapper;

    @Autowired
    private PaymentRecordMapper paymentRecordMapper;


    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // =================== 学生端 ===================

    /**
     * 学生查看有效缴费项目
     */
    @Override
    public Result<?> getActivePaymentItems(String studentId) {
        try {
            List<PaymentItem> activeItems = paymentItemMapper.getActiveItems();
            return Result.success("获取有效缴费项目成功", activeItems);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("获取有效缴费项目失败：" + e.getMessage());
        }
    }

    /**
     * 学生查看个人缴费记录
     */
    @Override
    public Result<?> getMyPaymentRecords(String studentId) {
        if (studentId == null || studentId.trim().isEmpty()) {
            return Result.fail("学生ID不能为空");
        }

        try {
            List<PaymentRecord> records = paymentRecordMapper.getStudentRecords(studentId);
            // 可以在这里补充查询每条记录对应的缴费项目名称等信息
            return Result.success("获取个人缴费记录成功", records);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("获取个人缴费记录失败：" + e.getMessage());
        }
    }

    /**
     * 学生缴纳费用
     */
    @Override
    @Transactional
    public Result<?> payForItem(Integer itemId, String studentId) {
        if (itemId == null || studentId == null || studentId.trim().isEmpty()) {
            return Result.fail("项目ID和学生ID不能为空");
        }

        try {
            // 1. 检查项目是否存在且有效
            PaymentItem item = paymentItemMapper.getById(itemId);
            if (item == null) {
                return Result.fail("缴费项目不存在");
            }

            // 2. 检查项目是否在有效期内
            Date now = new Date();
            if (item.getStartTime().after(now) || item.getEndTime().before(now)) {
                return Result.fail("该项目不在缴费有效期内");
            }

            // 3. 检查是否已缴费
            PaymentRecord paidRecord = paymentRecordMapper.checkIfPaid(itemId, studentId);
            if (paidRecord != null) {
                return Result.fail("您已缴纳该项目费用，无需重复缴纳");
            }

            // 4. 创建缴费记录（实际项目中这里会对接支付系统）
            PaymentRecord record = new PaymentRecord();
            record.setStudentId(studentId);
            record.setItemId(itemId);
            record.setPaymentStatus("PAID"); // 假设支付成功
            record.setCreateTime(new Date());
            record.setPaymentTime(new Date());

            int rows = paymentRecordMapper.addPaymentRecord(record);
            if (rows > 0) {
                return Result.success("缴费成功", record);
            } else {
                return Result.fail("缴费记录创建失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 事务会自动回滚
            return Result.fail("缴费失败：" + e.getMessage());
        }
    }

    // =================== 管理员端 ===================

    // =================== 管理员端 ===================
    /**
     * 管理员发布缴费项目
     */
    @Override
    @Transactional
    public Result<?> addPaymentItem(PaymentItem paymentItem) {
        // ===== 参数校验 =====
        if (paymentItem.getItemName() == null || paymentItem.getItemName().trim().isEmpty()) {
            return Result.fail("项目名称不能为空");
        }
        if (paymentItem.getItemType() == null || paymentItem.getItemType().trim().isEmpty()) {
            return Result.fail("项目类型不能为空");
        }
        if (paymentItem.getAmount() == null || paymentItem.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return Result.fail("金额必须为正数");
        }
        if (paymentItem.getEndTime() == null) {
            return Result.fail("截止时间不能为空");
        }
        if (paymentItem.getStatus() == null ||
                (!"ACTIVE".equals(paymentItem.getStatus()) && !"INACTIVE".equals(paymentItem.getStatus()))) {
            return Result.fail("状态错误，仅支持 ACTIVE（发布）或 INACTIVE（草稿）");
        }

        try {
            // 自动生成开始时间和创建时间
            Date startDate = new Date();
            paymentItem.setStartTime(startDate);
            paymentItem.setCreateTime(new Date());

            // 检查时间有效性
            if (paymentItem.getStartTime().after(paymentItem.getEndTime())) {
                return Result.fail("开始时间不能晚于结束时间");
            }

            // ===== 插入缴费项目 =====
            int rows = paymentItemMapper.addPaymentItem(paymentItem);
            if (rows <= 0) {
                return Result.fail("缴费项目发布失败");
            }

            // ===== 只有发布状态才生成缴费记录 =====
            int recordRows = 0;
            if ("ACTIVE".equals(paymentItem.getStatus())) {
                recordRows = paymentRecordMapper.initPaymentRecords(paymentItem.getId());
            }

            return Result.success(
                    "缴费项目保存成功" +
                            ("ACTIVE".equals(paymentItem.getStatus()) ?
                                    "，并已为 " + recordRows + " 位学生生成缴费任务" :
                                    "（草稿状态，未生成缴费任务）"),
                    paymentItem
            );

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("发布缴费项目失败：" + e.getMessage());
        }
    }

    /**
     * 管理员查看所有缴费项目
     */
    @Override
    public Result<?> getAllPaymentItems(Integer pageNum, Integer pageSize) {
        try {
            // 计算起始索引
            int startIndex = (pageNum - 1) * pageSize;

            // 获取分页数据
            List<PaymentItem> items = paymentItemMapper.getAllItemsByPage(startIndex, pageSize);

            // 获取总记录数
            int total = paymentItemMapper.getItemsTotalCount();

            // 构建分页结果
            Map<String, Object> result = new HashMap<>();
            result.put("items", items);
            result.put("total", total);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            result.put("totalPages", (total + pageSize - 1) / pageSize);

            return Result.success("获取所有缴费项目成功", result);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("获取所有缴费项目失败：" + e.getMessage());
        }
    }
    /**
     * 按项目名称模糊查询缴费项目（支持分页）
     */
    @Override
    public Result<?> searchItemsByName(String itemName, Integer pageNum, Integer pageSize, String status) {
        try {
            // 计算分页起始位置
            int startIndex = (pageNum - 1) * pageSize;

            // 封装查询参数
            Map<String, Object> params = new HashMap<>();

            params.put("itemName", itemName);
            params.put("startIndex", startIndex);
            params.put("pageSize", pageSize);
            params.put("status", status);

            // 查询分页数据
            List<PaymentItem> items = paymentItemMapper.searchItemsByName(params);

            // 查询总记录数
            int total = paymentItemMapper.countItemsByName(itemName);

            // 构建分页结果
            Map<String, Object> result = new HashMap<>();
            result.put("items", items);
            result.put("total", total);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            result.put("totalPages", (total + pageSize - 1) / pageSize);

            return Result.success("查询成功", result);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("查询失败：" + e.getMessage());
        }
    }



    /**
     * 管理员获取所有缴费记录（前端展示）
     */

    @Override
    public Page<PaymentRecord> getAllPaymentRecordsByPage(
            Integer pageNum, Integer pageSize, String studentId,
            Integer itemId, String paymentStatus, String startDate,
            String endDate, String itemName, String itemType) {
        // 校验分页参数，设置默认值（避免null错误）
        if (pageNum == null || pageNum < 1) {
            pageNum = 1; // 默认第一页
        }
        if (pageSize == null || pageSize < 1 || pageSize > 100) {
            pageSize = 10; // 默认每页10条，最大100条
        }

        // 使用PageHelper设置分页，紧跟的第一个查询会被自动分页
        PageHelper.startPage(pageNum, pageSize);

        // 调用Mapper查询，返回的List实际是Page对象（包含分页信息）
        List<PaymentRecord> records = paymentRecordMapper.selectAllPaymentRecords(
                studentId, itemId,paymentStatus, startDate, endDate,itemName, itemType);

        // 强转为Page对象，包含总条数、总页数等信息
        return (Page<PaymentRecord>) records;
    }
    @Override
    public PaymentRecord getPaymentRecordById(Integer recordId) {
        if (recordId == null) {
            return null;
        }
        return paymentRecordMapper.selectByPrimaryKey(recordId);
    }

    @Override
    public PaymentRecord selectByStudentIdAndItemId(String studentId, Integer itemId) {
        return paymentRecordMapper.selectByStudentIdAndItemId(studentId, itemId);
    }


    /**
     * 导出缴费记录
     */

    public void exportPaymentRecords(
            Integer itemId,
            String studentId,
            String paymentStatus,
            String startDate,  // 新增：如果需要按日期筛选
            String endDate,    // 新增：如果需要按日期筛选
            String itemName,   // 新增：如果需要按项目名称筛选
            String itemType,   // 新增：如果需要按项目类型筛选
            HttpServletResponse response) throws IOException {

        // 1. 复用分页查询方法获取所有符合条件的记录（不分页）
        // 传入pageNum=1，pageSize=Integer.MAX_VALUE获取全部数据
        Page<PaymentRecord> page = getAllPaymentRecordsByPage(
                1,                  // 页码：第一页
                Integer.MAX_VALUE,  // 每页条数：最大值，确保获取所有数据
                studentId,
                itemId,
                paymentStatus,
                startDate,
                endDate,
                itemName,
                itemType);
        List<PaymentRecord> records = page.getResult();  // 获取所有记录

        // 2. 后续Excel处理逻辑不变（与原代码一致）
        ExcelWriter writer = ExcelUtil.getWriter();

        // 3. 自定义表头别名
        writer.addHeaderAlias("recordId", "记录ID");
        writer.addHeaderAlias("studentId", "学生ID");
        writer.addHeaderAlias("itemId", "项目ID");
        writer.addHeaderAlias("itemName", "项目名称");
        writer.addHeaderAlias("itemType", "项目类型");
        writer.addHeaderAlias("amount", "金额");
        writer.addHeaderAlias("paymentStatus", "缴费状态");
        writer.addHeaderAlias("paymentTime", "缴费时间");
        writer.addHeaderAlias("endTime", "截止时间");
        writer.addHeaderAlias("createTime", "创建时间");

        // 4. 处理枚举值显示
        for (PaymentRecord record : records) {
            if ("PAID".equals(record.getPaymentStatus())) {
                record.setPaymentStatus("已缴费");
            } else if ("UNPAID".equals(record.getPaymentStatus())) {
                record.setPaymentStatus("未缴费");
            }
        }

        // 5. 写入数据
        writer.write(records, true);

        // 6. 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("缴费记录", StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        // 7. 输出并关闭资源
        try (ServletOutputStream out = response.getOutputStream()) {
            writer.flush(out, true);
        } finally {
            writer.close();
        }
    }




    /**
     * 管理员删除缴费项目
     */
    @Override
    public Result<?> deletePaymentItem(Integer itemId) {
        return paymentItemMapper.deletePaymentItem(itemId) > 0
                ? Result.success("删除缴费项目成功", itemId)
                : Result.fail("删除缴费项目失败");
    }

    /**
     * 管理员更新缴费项目（所有字段可更新，自动将开始时间设为当前时间）
     */
    /**
     * 管理员更新缴费项目（所有字段可更新）
     */
    @Override
    @Transactional
    public Result<?> updatePaymentItem(PaymentItem item) {
        // ===== 参数校验 =====
        if (item.getId() == null) {
            return Result.fail("更新时必须提供项目ID");
        }
        if (item.getItemName() == null || item.getItemName().trim().isEmpty()) {
            return Result.fail("项目名称不能为空");
        }
        if (item.getItemType() == null || item.getItemType().trim().isEmpty()) {
            return Result.fail("项目类型不能为空");
        }
        if (item.getAmount() == null || item.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return Result.fail("金额必须为正数");
        }
        if (item.getEndTime() == null) {
            return Result.fail("截止时间不能为空");
        }
        if (item.getStatus() == null ||
                (!"ACTIVE".equals(item.getStatus()) && !"INACTIVE".equals(item.getStatus()))) {
            return Result.fail("状态错误，仅支持 ACTIVE（发布）或 INACTIVE（草稿）");
        }

        try {
            // 查询原始数据，判断状态是否发生变化
            PaymentItem oldItem = paymentItemMapper.getPaymentItemById(item.getId());
            if (oldItem == null) {
                return Result.fail("未找到对应的缴费项目");
            }

            // 自动将开始时间设置为当前系统时间
            item.setStartTime(new Date());

            // 检查时间有效性
            if (item.getEndTime() != null && item.getStartTime().after(item.getEndTime())) {
                return Result.fail("开始时间不能晚于结束时间");
            }

            // ===== 执行更新（Mapper 中 update_time 可以用 NOW()） =====
            int rows = paymentItemMapper.updatePaymentItem(item);
            if (rows <= 0) {
                return Result.fail("更新缴费项目失败");
            }

            int recordRows = 0;
            // 状态从草稿变为发布时，为所有学生生成缴费记录
            if ("INACTIVE".equals(oldItem.getStatus()) && "ACTIVE".equals(item.getStatus())) {
                recordRows = paymentRecordMapper.initPaymentRecords(item.getId());
            }

            return Result.success(
                    "缴费项目更新成功" +
                            (recordRows > 0 ? "，并已为 " + recordRows + " 位学生生成缴费任务" : ""),
                    item
            );

        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("更新缴费项目失败：" + e.getMessage());
        }
    }



    @Override
    public int batchUpdateStatus(String studentId, List<Integer> itemIds, String paymentStatus) {
        // 构建更新参数
        PaymentRecord record = new PaymentRecord();
        record.setStudentId(studentId);
        record.setPaymentStatus(paymentStatus);

        // 如果是"已支付"状态，更新支付时间
        if ("PAID".equals(paymentStatus)) {
            record.setPaymentTime(new Date());
        }

        // 调用Mapper批量更新
        return paymentRecordMapper.batchUpdateStatus(record, itemIds);
    }
}